package com.cleaner.base

import android.app.Activity
import android.app.Application
import android.content.ComponentCallbacks
import android.content.Context
import android.content.res.Configuration
import android.os.Bundle
import com.cleaner.base.utils.ActivityLifecycleListener
import com.cleaner.base.utils.Events

open class BaseApplication : Application() {

    // 该值根据实际UI出图进行修改
    protected open val designSize = 360

    override fun onCreate() {
        super.onCreate()
        app = this

        registerComponentCallbacks()
        registerActivityLifecycleCallbacks()
        setDensity(designSize)

        Events.initialize(this)
    }

    private fun registerComponentCallbacks() = registerComponentCallbacks(object : ComponentCallbacks {
        override fun onConfigurationChanged(newConfig: Configuration) {
            if (newConfig.fontScale <= 0) return
            this@BaseApplication.setDensity(designSize)
        }

        override fun onLowMemory() = Unit
    })

    private fun registerActivityLifecycleCallbacks() {
        registerActivityLifecycleCallbacks(object : ActivityLifecycleListener() {
            override fun onActivityCreated(activity: Activity, savedInstanceState: Bundle?) {
                activity.setDensity()
            }
        })
    }

    companion object {
        private lateinit var app: BaseApplication
        val context: Context
            get() = app
    }

}

val appContext: Context
    get() = BaseApplication.context

private fun Activity.setDensity() {
    val displayMetrics = resources.displayMetrics
    application.resources.displayMetrics.run {
        displayMetrics.density = density
        displayMetrics.scaledDensity = scaledDensity
        displayMetrics.densityDpi = densityDpi
    }
}

private fun Application.setDensity(designSize: Int) {
    val displayMetrics = resources.displayMetrics
    val density = displayMetrics.density
    val scaledDensity = displayMetrics.scaledDensity

    val targetDensity = displayMetrics.widthPixels / designSize.toFloat()
    val targetScaledDensity = targetDensity * (scaledDensity / density)
    val targetDensityDpi = 160 * targetDensity.toInt()

    displayMetrics.density = targetDensity
    displayMetrics.scaledDensity = targetScaledDensity
    displayMetrics.densityDpi = targetDensityDpi
}
